<?php
/**
 * Created by PhpStorm.
 * User: 'mrzhan'
 * Date: 2021/1/7
 * Time: 22:40
 */

namespace App\Controller;

use Hyperf\Guzzle\ClientFactory;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Utils\Coroutine;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\Parallel;
use parallel\Channel;
use Swoole\Coroutine\WaitGroup;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;

/**
 * @Controller
 * Class CoAcController
 * @package App\Controller
 */
class CoController
{


    public function sleep(RequestInterface $request)
    {

      $seconds =  $request->query('seconds',1);
      sleep($seconds);
      return $seconds;

    }


    /**
     * @RequestMapping(path="test",methods="get,post")
     * @param ClientFactory $clientFactory
     * @return array
     */
    public function test(ClientFactory $clientFactory)
    {
//        $client = $clientFactory->create();
//        $client->get('127.0.0.1:9502/co/sleep?seconds=2');
//        return 1;


        $channel = new \Swoole\Coroutine\Channel();

        co(function() use ($clientFactory,$channel){
            $client = $clientFactory->create();
            $client->get('127.0.0.1:9502/co/sleep?seconds=2');
            $channel->push(123);
        });

        co(function() use ($clientFactory,$channel){
            $client = $clientFactory->create();
            $client->get('127.0.0.1:9502/co/sleep?seconds=2');
            $channel->push(321);
        });

        $result[] = $channel->pop();
        $result[] = $channel->pop();
        return $result;

    }

    public function test03()
    {
        $channel = new \Swoole\Coroutine\Channel();

        co(function () use ($channel){
            $channel->push(1);
        });

        co(function () use ($channel) {
            $channel->push(2);
        });

        $result[] = $channel->pop();
        $result[] = $channel->pop();

        return $result;

    }


    public function test1(ClientFactory $clientFactory)
    {

        $wg = new WaitGroup();

        $result = [];
        $wg->add(2);
        co(function() use ($wg,$clientFactory,&$result){
            $client = $clientFactory->create();
            $client->get('127.0.0.1:9502/co/sleep?seconds=1');
            $result[] = 123;
            $wg->done();
        });

        co(function() use ($wg,$clientFactory,&$result){
            $client = $clientFactory->create();
            $client->get('127.0.0.1:9502/co/sleep?seconds=1');
            $result[] = 321;
            $wg->done();
        });

        $wg->wait();
        return $result;

    }

    public function test10()
    {
        $waitGroup = new WaitGroup();
        $result = [];
        $waitGroup->add(2);
        co(function () use ($waitGroup,&$result){
            sleep(2);
            $result[] = 1;
            $waitGroup->done();
        });

        co(function () use ($waitGroup, &$result){
            sleep(2);
            $result[] = 2;
            $waitGroup->done();
        });

        $waitGroup->wait();
        return $result;

    }



    public function test2(ClientFactory $clientFactory)
    {

        $parallel = new Parallel();

        $parallel->add(function() use ($clientFactory){
            $client = $clientFactory->create();
            $client->get('127.0.0.1:9502/co/sleep?seconds=1');
            return 123;
        },'key1');

        $parallel->add(function () use ($clientFactory) {
            $client = $clientFactory->create();
            $client->get('127.0.0.1:9502/co/sleep?seconds=1');
            return 321;
        },'key2');

       $result = $parallel->wait();
       return $result;


    }


    /**
     * @return array
     */
    public function test21()
    {
        $parallel = new Parallel();
        $parallel->add(function(){
            return 1;
        },'keyOne');

        $parallel->add(function (){
            return 2;
        },'keyTwo');

        $result = $parallel->wait();

        return $result;

    }




    public function test20()
    {
         $par = new Parallel();
         $par->add(function (){
             return 2;
         },'id');

         $par->add(function (){
             return 3;
         });

         $result = $par->wait();

         return $result;

    }





    public function test3(ClientFactory $clientFactory)
    {

      $result =  Parallel([
            function () use ($clientFactory) {
                $client = $clientFactory->create();
                $client->get('127.0.0.1:9502/co/sleep?seconds=1');
                return 321;
            },
            function() use ($clientFactory){
                $client = $clientFactory->create();
                $client->get('127.0.0.1:9502/co/sleep?seconds=1');
                return 123;
            }

        ]);

      return $result;
    }



    public function test31()
    {
       $par = Parallel([
            function () {
                return 4;
            },
            function () {
                return 3;
            }
        ]);


       return $par;

    }


    public function test32()
    {
        $par = Parallel([
            function() {
                return 3;
            },
            function() {
                return 4;
            }
        ]);

        return $par;
    }


    public function test5()
    {
        $channel = new \Swoole\Coroutine\Channel();
        co(function () use ($channel){
            sleep(1);
            echo 1,"\n";
            $channel->push(1);
        });

        co(function () use ( $channel){
            sleep(1);
            echo 2,"\n";
            $channel->push(2);
        });

        $result = [];
        $result[] = $channel->pop();
        $result[] = $channel->pop();
        return $result;

    }

    public function test6()
    {
        $channel = new \Swoole\Coroutine\Channel();

        co(function () use ($channel) {
            sleep(2);
            $channel->push(1);
        });

        co(function () use ($channel){
            sleep(2);
            $channel->push(2);
        });

        $result[] = $channel->pop();
        $result[] = $channel->pop();

        return $result;

    }



    public function test7()
    {
        $channel = new \Swoole\Coroutine\Channel();

        co(function () use ($channel) {
            sleep(1);
            $channel->push('1');
        });

        co(function ()use ($channel){
            sleep(2);
            $channel->push(2);
        });

        $result[] =$channel->pop();
        $result[] =$channel->pop();

        return $result;

    }




}
